<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Show the path Dynamicly</title>
  </head>
  <style>
    :root {
      --FONT-SIZE: 32px;
      --STROKE-WIDTH: 4px;
      --C-WHITE: #f3f3f3;
      --C-BLACK: #333;
      --C-BLUE: #99f;
      --C-RED: #f99;
      --LENGTH-WIDTH: 200px;
      --LENGTH-HEIGHT: calc(var(--FONT-SIZE) + 8px);
      --PAD-TOP: 0;
      --PAD-LEFT: calc(50% - (var(--LENGTH-WIDTH) / 2));
    }

    body {
      overflow: scroll;
      background-color: var(--C-BLACK);
      font-family: Consolas, "Courier New", monospace;
    }

    #IPT_DIV {
      position: fixed;
      display: flex;
      place-content: center center;
      top: var(--PAD-TOP);
      left: var(--PAD-LEFT);
      width: var(--LENGTH-WIDTH);
      height: var(--LENGTH-HEIGHT);
      background-color: var(--C-WHITE);
      visibility: hidden;
      text-align: center;

      & input {
        width: 100%;
        text-align: center;
        font-size: var(--FONT-SIZE);
      }
    }

    main {
      width:  600em;
      margin: 0 auto;
      padding: 0;
    }

    .nums {
      display: inline-block;
      /* float: left; */
      font-size: var(--FONT-SIZE);

      & > p {
        width: 100%;
        clear: both;
        margin: 0 4px;
        padding: 0;
        outline: 1px solid var(--C-WHITE);
        text-align: center;
        line-height: 1em;
        color: var(--C-WHITE);
      }

      &:not(:last-child) > p {
        color: var(--C-BLUE);
      }
      &:last-child:nth-child(3) > p {
        color: var(--C-RED);
      }
    }
  </style>

  <body>
    <div id="IPT_DIV">
      <input type="text" title="input hex numbers" />
    </div>

    <main>
      <!-- <div class="nums">
        <p>123</p>
        <div class="nums">
          <p>231</p>
          <div class="nums">
            <p>243</p>
            <div class="nums"><p>0313</p></div>
          </div>
        </div>
        <div class="nums">
          <p>344</p>
          <div class="nums">
            <p>344</p>
            <div class="nums"><p>02213</p></div>
            <div class="nums"><p>0313</p></div>
          </div>
          <div class="nums">
            <p>344</p>
            <div class="nums"><p>02213</p></div>
            <div class="nums"><p>0313</p></div>
          </div>
        </div>
      </div> -->
    </main>
  </body>

  <!-- <script type="module" src="./tpo2n.mjs"></script> -->
  <script type="module" src="./tpo2p.mjs"></script>
  <script type="module">
    import { prev } from "./tpo2p.mjs";
    // import { next } from "./tpo2n.mjs";
    const prevStr = (str) => prev(str.split("").map((e) => +e)).join("");
    // const nextStr = (str) => next(str.split("").map((e) => +e)).join("");

    const MAIN = document.querySelector("main");
    const IPT_DIV = document.getElementById("IPT_DIV");
    // Input Control
    const IPT = IPT_DIV.firstElementChild;

    IPT.addEventListener("blur", () => {
      // hide input div
      IPT_DIV.style.visibility = "hidden";
    });

    // Check input nums is valid or not
    const REG = /^[0-5]+$/;

    // While change input value
    const iptChange = (force = false) => {
      if (!ROOT_NUMS) return null;
      if (!force && IPT.value === ROOT_NUMS.nums) return null;
      if (!REG.test(IPT.value)) {
        IPT.value = ROOT_NUMS.nums || "0";
        alert("Error input");
        return null;
      }
      // update nums
      ROOT_NUMS.nums = IPT.value;
      newTree();
    };
    IPT.addEventListener("change", () => iptChange(false));

    const MAX_LEVEL = 16;
    var ROOT_NUMS = null;

    const newTree = () => {
      if (!ROOT_NUMS?.nums) return null;

      MAIN.innerHTML = "";
      ROOT_NUMS.elm.replaceChildren();
      ROOT_NUMS.elm.appendChild(ROOT_NUMS.p);
      MAIN.appendChild(ROOT_NUMS.elm);

      ROOT_NUMS.children.length = 0;

      const iter = (node, level) => {
        if (level >= MAX_LEVEL) return null;

        let pNums = prevStr(node.nums);

        if (node.end === "2") {
          let c1 = new HexNumbsers(pNums.slice(0, -1));
          c1.parent = node;
          node.children.push(c1);
          node.elm.appendChild(c1.elm);
          // recursion
          iter(c1, level + 1);
        }

        let c0 = new HexNumbsers(pNums);
        c0.parent = node;
        node.children.push(c0);
        node.elm.appendChild(c0.elm);
        // recursion
        iter(c0, level + 1);
      };

      iter(ROOT_NUMS, 0);
    };

    class HexNumbsers {
      parent = null;
      children = [];

      constructor(nums = "0") {
        this._nums = nums;
        this.elm = document.createElement("div");
        this.elm.className = "nums";
        this.elm.obj = this;

        this.p = document.createElement("p");
        this.p.textContent = this._nums;
        this.elm.appendChild(this.p);

        // Double click event, omit single click
        this.p.addEventListener("dblclick", (evn) => {
          if (ROOT_NUMS === this) {
            IPT_DIV.style.visibility = "visible";
            return null;
          }

          ROOT_NUMS = this;
          IPT_DIV.style.visibility = "hidden";
          IPT.value = this.nums;
          iptChange(true);
        });
      }

      get nums() {
        return this._nums;
      }

      set nums(n) {
        if (this._nums === n) return null;
        this._nums = n;
        this.p.textContent = n;
      }

      get end() {
        return this._nums?.charAt(this._nums?.length - 1);
      }
    }

    // test unit
    (() => {
      let n1 = new HexNumbsers("12");
      IPT.value = "12";
      n1.p.dispatchEvent(new MouseEvent("dblclick"));
      iptChange(true);
    })();
  </script>
</html>
